import { folderModel, scriptModel, type IFolder } from '../database/models';

export interface CreateFolderData {
  name: string;
  parent_id?: string;
  created_by?: string;
}

export interface UpdateFolderData {
  name?: string;
  parent_id?: string;
}

export class FolderService {
  // 创建文件夹
  async createFolder(data: CreateFolderData): Promise<IFolder> {
    // 验证文件夹数据
    this.validateFolderData(data);
    
    // 验证父文件夹是否存在
    if (data.parent_id) {
      const parentFolder = await folderModel.findById(data.parent_id);
      if (!parentFolder) {
        throw new Error('父文件夹不存在');
      }
    }
    
    // 检查同级文件夹名称是否唯一
    const isNameUnique = await folderModel.isNameUniqueInParent(data.name, data.parent_id);
    if (!isNameUnique) {
      throw new Error('同级目录下已存在相同名称的文件夹');
    }
    
    return await folderModel.createFolder(data);
  }
  
  // 更新文件夹
  async updateFolder(id: string, data: UpdateFolderData): Promise<IFolder | null> {
    const existingFolder = await folderModel.findById(id);
    if (!existingFolder) {
      throw new Error('文件夹不存在');
    }
    
    // 如果更新名称
    if (data.name && data.name !== existingFolder.name) {
      this.validateFolderData({ name: data.name });
      
      // 检查同级文件夹名称是否唯一
      const isNameUnique = await folderModel.isNameUniqueInParent(
        data.name, 
        data.parent_id || existingFolder.parent_id, 
        id
      );
      if (!isNameUnique) {
        throw new Error('同级目录下已存在相同名称的文件夹');
      }
      
      return await folderModel.renameFolder(id, data.name);
    }
    
    // 如果移动文件夹
    if (data.parent_id !== undefined && data.parent_id !== existingFolder.parent_id) {
      // 验证目标父文件夹
      if (data.parent_id) {
        const parentFolder = await folderModel.findById(data.parent_id);
        if (!parentFolder) {
          throw new Error('目标父文件夹不存在');
        }
      }
      
      // 检查名称冲突
      const isNameUnique = await folderModel.isNameUniqueInParent(
        existingFolder.name, 
        data.parent_id, 
        id
      );
      if (!isNameUnique) {
        throw new Error('目标位置已存在相同名称的文件夹');
      }
      
      return await folderModel.moveFolder(id, data.parent_id);
    }
    
    return existingFolder;
  }
  
  // 删除文件夹
  async deleteFolder(id: string, options: {
    force?: boolean; // 是否强制删除（包含子文件夹和脚本）
  } = {}): Promise<boolean> {
    const folder = await folderModel.findById(id);
    if (!folder) {
      throw new Error('文件夹不存在');
    }
    
    // 检查是否有子文件夹
    const childFolders = await folderModel.getChildFolders(id);
    if (childFolders.length > 0 && !options.force) {
      throw new Error('文件夹包含子文件夹，请先删除子文件夹或使用强制删除');
    }
    
    // 检查是否有脚本
    const scripts = await scriptModel.findByFolderId(id);
    if (scripts.length > 0 && !options.force) {
      throw new Error('文件夹包含脚本，请先移动或删除脚本或使用强制删除');
    }
    
    return await folderModel.deleteFolder(id);
  }
  
  // 获取文件夹详情
  async getFolder(id: string): Promise<IFolder | null> {
    return await folderModel.findById(id);
  }
  
  // 获取文件夹树结构
  async getFolderTree(): Promise<any[]> {
    return await folderModel.getFolderTree();
  }
  
  // 获取子文件夹
  async getChildFolders(parentId?: string): Promise<IFolder[]> {
    return await folderModel.getChildFolders(parentId);
  }
  
  // 获取文件夹内容（包含子文件夹和脚本）
  async getFolderContents(folderId?: string): Promise<{
    folder: IFolder | null;
    subfolders: IFolder[];
    scripts: any[];
    stats: {
      total_subfolders: number;
      total_scripts: number;
      total_size: number;
    };
  }> {
    let folder: IFolder | null = null;
    let stats = { total_subfolders: 0, total_scripts: 0, total_size: 0 };
    
    if (folderId) {
      folder = await folderModel.findById(folderId);
      if (!folder) {
        throw new Error('文件夹不存在');
      }
      stats = await folderModel.getFolderStats(folderId);
    }
    
    const subfolders = await folderModel.getChildFolders(folderId);
    const scripts = await scriptModel.findByFolderId(folderId || null);
    
    return {
      folder,
      subfolders,
      scripts,
      stats
    };
  }
  
  // 移动文件夹
  async moveFolder(id: string, newParentId?: string): Promise<IFolder | null> {
    const folder = await folderModel.findById(id);
    if (!folder) {
      throw new Error('文件夹不存在');
    }
    
    // 验证目标父文件夹
    if (newParentId) {
      const parentFolder = await folderModel.findById(newParentId);
      if (!parentFolder) {
        throw new Error('目标父文件夹不存在');
      }
    }
    
    // 检查名称冲突
    const isNameUnique = await folderModel.isNameUniqueInParent(folder.name, newParentId, id);
    if (!isNameUnique) {
      throw new Error('目标位置已存在相同名称的文件夹');
    }
    
    return await folderModel.moveFolder(id, newParentId);
  }
  
  // 重命名文件夹
  async renameFolder(id: string, newName: string): Promise<IFolder | null> {
    const folder = await folderModel.findById(id);
    if (!folder) {
      throw new Error('文件夹不存在');
    }
    
    this.validateFolderData({ name: newName });
    
    // 检查同级文件夹名称是否唯一
    const isNameUnique = await folderModel.isNameUniqueInParent(newName, folder.parent_id, id);
    if (!isNameUnique) {
      throw new Error('同级目录下已存在相同名称的文件夹');
    }
    
    return await folderModel.renameFolder(id, newName);
  }
  
  // 复制文件夹
  async copyFolder(id: string, newName: string, parentId?: string, createdBy?: string): Promise<IFolder> {
    const originalFolder = await folderModel.findById(id);
    if (!originalFolder) {
      throw new Error('原文件夹不存在');
    }
    
    // 验证目标父文件夹
    if (parentId) {
      const parentFolder = await folderModel.findById(parentId);
      if (!parentFolder) {
        throw new Error('目标父文件夹不存在');
      }
    }
    
    // 检查名称唯一性
    const isNameUnique = await folderModel.isNameUniqueInParent(newName, parentId);
    if (!isNameUnique) {
      throw new Error('目标位置已存在相同名称的文件夹');
    }
    
    // 创建新文件夹
    const newFolder = await folderModel.createFolder({
      name: newName,
      parent_id: parentId,
      created_by: createdBy
    });
    
    // 递归复制子文件夹和脚本
    await this.copyFolderContents(id, newFolder.id, createdBy);
    
    return newFolder;
  }
  
  // 获取文件夹路径
  async getFolderPath(id: string): Promise<string> {
    const folder = await folderModel.findById(id);
    if (!folder) {
      throw new Error('文件夹不存在');
    }
    
    return folder.path;
  }
  
  // 搜索文件夹
  async searchFolders(keyword: string, options: {
    parent_id?: string;
    created_by?: string;
    limit?: number;
    offset?: number;
  } = {}): Promise<{
    folders: IFolder[];
    total: number;
  }> {
    const limit = options.limit || 20;
    const offset = options.offset || 0;
    
    let whereConditions = `name ILIKE $1 OR path ILIKE $1`;
    const params: any[] = [`%${keyword}%`];
    let paramIndex = 2;
    
    if (options.parent_id) {
      whereConditions += ` AND parent_id = $${paramIndex++}`;
      params.push(options.parent_id);
    }
    
    if (options.created_by) {
      whereConditions += ` AND created_by = $${paramIndex++}`;
      params.push(options.created_by);
    }
    
    const folders = await folderModel.findAll({
      where: whereConditions,
      limit,
      offset,
      orderBy: 'name',
      orderDirection: 'ASC'
    });
    
    const total = await folderModel.count({ name: keyword }); // 简化计数
    
    return { folders, total };
  }
  
  // 获取文件夹统计信息
  async getFolderStats(id: string): Promise<{
    folder: IFolder;
    stats: {
      total_scripts: number;
      total_subfolders: number;
      total_size: number;
    };
    depth: number;
    breadcrumb: Array<{ id: string; name: string; path: string }>;
  }> {
    const folder = await folderModel.findById(id);
    if (!folder) {
      throw new Error('文件夹不存在');
    }
    
    const stats = await folderModel.getFolderStats(id);
    
    // 计算文件夹深度
    const depth = folder.path.split('/').length - 1;
    
    // 构建面包屑导航
    const breadcrumb = await this.buildBreadcrumb(folder.path);
    
    return {
      folder,
      stats,
      depth,
      breadcrumb
    };
  }
  
  // 批量操作文件夹
  async batchOperateFolders(folderIds: string[], operation: 'delete' | 'move', options: {
    target_parent_id?: string;
    force?: boolean;
  } = {}): Promise<{
    success_count: number;
    failed_count: number;
    errors: string[];
  }> {
    let successCount = 0;
    let failedCount = 0;
    const errors: string[] = [];
    
    for (const folderId of folderIds) {
      try {
        if (operation === 'delete') {
          await this.deleteFolder(folderId, { force: options.force });
          successCount++;
        } else if (operation === 'move') {
          await this.moveFolder(folderId, options.target_parent_id);
          successCount++;
        }
      } catch (error) {
        failedCount++;
        errors.push(`文件夹 ${folderId}: ${error.message}`);
      }
    }
    
    return {
      success_count: successCount,
      failed_count: failedCount,
      errors
    };
  }
  
  // 验证文件夹数据
  private validateFolderData(data: Partial<CreateFolderData>): void {
    if (data.name) {
      if (data.name.length < 1 || data.name.length > 255) {
        throw new Error('文件夹名称长度必须在1-255个字符之间');
      }
      
      if (!/^[a-zA-Z0-9\u4e00-\u9fa5_\-\s]+$/.test(data.name)) {
        throw new Error('文件夹名称只能包含字母、数字、中文、下划线、连字符和空格');
      }
      
      if (data.name.startsWith('.') || data.name.endsWith('.')) {
        throw new Error('文件夹名称不能以点号开头或结尾');
      }
    }
  }
  
  // 递归复制文件夹内容
  private async copyFolderContents(sourceFolderId: string, targetFolderId: string, createdBy?: string): Promise<void> {
    // 复制子文件夹
    const childFolders = await folderModel.getChildFolders(sourceFolderId);
    for (const childFolder of childFolders) {
      const newChildFolder = await folderModel.createFolder({
        name: childFolder.name,
        parent_id: targetFolderId,
        created_by: createdBy
      });
      
      // 递归复制子文件夹内容
      await this.copyFolderContents(childFolder.id, newChildFolder.id, createdBy);
    }
    
    // 复制脚本
    const scripts = await scriptModel.findByFolderId(sourceFolderId);
    for (const script of scripts) {
      await scriptModel.create({
        name: `${script.name}_copy`,
        content: script.content,
        description: script.description ? `${script.description} (副本)` : undefined,
        tags: script.tags,
        folder_id: targetFolderId,
        created_by: createdBy
      });
    }
  }
  
  // 构建面包屑导航
  private async buildBreadcrumb(path: string): Promise<Array<{ id: string; name: string; path: string }>> {
    const pathParts = path.split('/').filter(part => part !== '');
    const breadcrumb = [];
    
    let currentPath = '';
    for (const part of pathParts) {
      currentPath += `/${part}`;
      
      const folder = await folderModel.findAll({
        where: { path: currentPath },
        limit: 1
      });
      
      if (folder.length > 0) {
        breadcrumb.push({
          id: folder[0].id,
          name: folder[0].name,
          path: folder[0].path
        });
      }
    }
    
    return breadcrumb;
  }
}